import axios, { type AxiosInstance, type AxiosRequestConfig, type AxiosResponse } from 'axios';
import { getSHA256 } from './crypto-util';
import { isObject } from '@/utils/verify';
import { refreshToken } from './refresh-token';
import type { AppStore } from '@/pinia/modules/app';
export type Response<T = unknown> = {
  code: number;
  msg: string;
  data: T;
};
/** 分页 */
export type Paging<T> = {
  /** 当前页 */
  current: number;
  /** 数据 */
  records: T[];
  /** 每页数量 */
  size: number;
  /** 总条数  */
  total: number;
};

export interface PageDataRequest {
  /**
   * 当前页
   */
  current: number;
  /**
   * 结束日期 yyyy-MM-dd
   */
  endDate?: string;
  /**
   * 每页数量
   */
  size: number;
  /**
   * 开始日期 yyyy-MM-dd
   */
  startDate?: string;
}

const instance: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_BASE_URL,
});

/** 通用请求头 */
instance.defaults.headers.common['Content-Type'] = 'application/json';

/** POST 方法请求头 */
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

/** 超时时间 */
instance.defaults.timeout = 60000;

/** 默认请求方式 */
instance.defaults.method = 'POST';

/** 校验状态码 */
instance.defaults.validateStatus = (status) => {
  return status === 200;
};

/** 请求前拦截 */
instance.interceptors.request.use(
  (config) => {
    try {
      config.headers = config.headers || {};
      const access_token = useUserStore().access_token;
      console.log(useUserStore(),"useUserStore()")
      config.headers['Dsbb-Custom-Mac'] = config.headers['Dsbb-Custom-Mac'] ?? navigator.userAgent;
      config.headers['Dsbb-Custom-Platform'] = config.headers['Dsbb-Custom-Platform'] ?? 'web';
      config.headers['Dsbb-Custom-Timestamp'] = config.headers['Dsbb-Custom-Timestamp'] ?? String(new Date().getTime());
      config.headers['Dsbb-Custom-Authorization'] = config.headers['Dsbb-Custom-Authorization'] ?? getCustomAuthorization(config, access_token);

      if (access_token) {
        config.headers['Dsbb-Custom-Access-Token'] = config.headers['Dsbb-Custom-Access-Token'] ?? access_token;
      }
      return Promise.resolve(config);
    } catch (e) {
      return Promise.reject(config);
    }
  },
  (config) => {
    const _config = (isObject(config) ? config : {}) as AxiosRequestConfig;
    return Promise.reject(_config);
  }
);

/** 请求后拦截 */
instance.interceptors.response.use(
  async (response): Promise<any> => {
    try {
      const userStore: UserStore = useUserStore();
      const appStore: AppStore = useAppStore();
      if (response.data && (isObject(response.data) || isBlob(response.data))) {
        try {
          if (isBlob(response.data)) {
            return Promise.resolve(response.data);
          } else if ('code' in response.data && response.data.code === 200) {
            return Promise.resolve(response.data);
          } else if ('code' in response.data && response.data.code === 40003) {
            if (!userStore.refresh_token) {
              useUserStore().logout(true);
              return Promise.reject(requestComFail(response));
            } else {
              try {
                const res = await refreshToken(userStore, appStore);
                response.config.headers!['Dsbb-Custom-Access-Token'] = res;
                return instance.request(response.config);
              } catch (error) {
                userStore.logout(true);
                return Promise.reject(requestComFail(response));
              }
            }
          } else if ('code' in response.data && response.data.code === 40005) {
            userStore.logout(true);
            return Promise.reject(requestComFail(response));
          } else {
            response.data = { code: response.data?.code ?? -20001, msg: response.data?.msg ?? '代码错误，BD2001' };
            return Promise.reject(requestComFail(response));
          }
        } catch (e) {
          response.data = { code: response.data?.code ?? -20002, msg: response.data?.msg || '请求失败，BD2002' };
          return Promise.reject(requestComFail(response));
        }
      } else {
        response.data = { code: -20003, msg: '数据格式错误，BD2003' };
        return Promise.reject({ code: -1003, msg: '请求失败，数据格式错误' });
      }
    } catch (e) {
      console.error('代码错误1：', e);
      response.data = { code: -20004, msg: '代码错误，BD004' };
      return Promise.reject(requestComFail(response));
    }
  },
  (response) => {
    const _response = response as AxiosResponse;
    _response.data = { code: -20006, msg: '请求失败，请确认地址是否正确，BD006' };
    return Promise.reject(requestComFail(_response));
  }
);

/** 得到自定义的验证 */
function getCustomAuthorization(config: AxiosRequestConfig, token: string | undefined): string {
  // json 转换一下排除 undefined等非法值
  const newData: Record<string, unknown> = JSON.parse(
    JSON.stringify({
      'Dsbb-Custom-Mac': config.headers?.['Dsbb-Custom-Mac'] || '',
      'Dsbb-Custom-Timestamp': config.headers?.['Dsbb-Custom-Timestamp'] || '',
      'Dsbb-Custom-Platform': config.headers?.['Dsbb-Custom-Platform'] || '',
      ...(isObject(config.params) ? config.params : {}),
      ...(isObject(config.data) ? config.data : {}),
    })
  );
  if (token) {
    newData.Token = token;
  }



  const keys: string[] = Object.keys(newData).sort();
  const str: string = keys.reduce((previousValue, currentValue) => {
    const value = newData[currentValue] && newData[currentValue] instanceof Object ? JSON.stringify(newData[currentValue]) : (newData[currentValue] ?? '');
    return `${previousValue}${currentValue}${value}`;
  }, '');
   console.log('需要加密的字符串====', str);


  const CustomAuthorization = getSHA256(str);
  return CustomAuthorization;
}

/** 是否未Blob */
function isBlob(obj: any): obj is Blob {
  return obj instanceof Blob;
}

/** 请求结果 */
function requestComFail(response: AxiosResponse): Response {
  const data = isObject(response.data) ? response.data : {};
  const status = 'status' in response ? response.status : -1;

  if (status !== 200) {
    if (!('code' in data) || !('msg' in data)) {
      data.code = -1000;
      data.msg = '请求失败，-1000';
    }
  }
  if (status === 404) {
    data.code = status;
    data.msg = '链接已失效，404';
  } else if (status === 500) {
    data.code = status;
    data.msg = '服务器内部错误，500';
  }
  const ersResult = { ...data, data: data.data || null } as Response;
  return ersResult;
}
export default instance;
